#!/bin/sh

kedr_module="@CMAKE_BINARY_DIR@/core/kedr.ko"
fault_simulation_module="@CMAKE_BINARY_DIR@/fault_simulation/kedr_fault_simulation.ko"

indicator_module="@CMAKE_CURRENT_BINARY_DIR@/../kedr_fsim_indicator_common.ko"
indicator_name="common"

simulation_module="@CMAKE_CURRENT_BINARY_DIR@/module/kedr_indicator_common_test_module.ko"
point_name="common"


debugfs="@KEDR_TEST_DIR@/test/debugfs"

point_dir="${debugfs}/kedr_fault_simulation/points/${point_name}"

simulate()
{
	echo 123 > "${debugfs}/kedr_indicator_common_test_module/simulate"
}


do_commands_script="sh @CMAKE_BINARY_DIR@/tests/scripts/do_commands.sh"
commands_file="@CMAKE_CURRENT_BINARY_DIR@/commands.txt"

cat > "$commands_file" << eof

on_load insmod "${kedr_module}" || ! printf "Cannot load kedr core module into kernel.\n"
on_unload rmmod "${kedr_module}" || ! printf "Cannot unload kedr core module.\n"
on_load insmod "${fault_simulation_module}" || ! printf "Cannot load fault simulation module into kernel.\n"
on_unload rmmod "${fault_simulation_module}" || ! printf "Cannot unload fault simulation module.\n"
on_load insmod "${simulation_module}" || ! printf "Cannot load module with simulation point into kernel.\n"
on_unload rmmod "${simulation_module}" || ! printf "Cannot unload module with simulation point.\n"
on_load insmod "${indicator_module}" || ! printf "Cannot load indicator module into kernel.\n"
on_unload rmmod "${indicator_module}" || ! printf "Cannot unload indicator module.\n"

on_load mkdir -p "${debugfs}"
on_load mount -t debugfs debugfs "${debugfs}"
on_unload umount "${debugfs}"

eof

if ! $do_commands_script "$commands_file" load; then
	printf "Cannot initialize test.\n"
	exit 1
fi

##
echo "$indicator_name" > "${point_dir}/current_indicator"

if test $? -ne 0; then
	printf "Cannot set indicator for the point.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if ! simulate; then
	printf "Simulate should't fail with default instance of indicator.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

##
echo "1" > "${point_dir}/expression"

if test $? -ne 0; then
	printf "Cannot set expression for the indicator.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if simulate; then
	printf "Simulate should fail with \"1\" expression.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

## Set indicator and expression at once.
echo "$indicator_name 1" > "${point_dir}/current_indicator"

if test $? -ne 0; then
	printf "Cannot set indicator with expression '1' for the point.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

expression=`cat "${point_dir}/expression"`
if test "$expression" != "1"; then
	printf "Indicator was set with expression '%s', but expression is '%s'.\n" "1" "$expression"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if simulate; then
	printf "Simulate should fail with \"1\" expression.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

##Cannot test in_init, because it is not target module ;)
cat > /dev/null << comment
echo "in_init" > "${point_dir}/expression"

if test $? -ne 0; then
	printf "Cannot set expression for the indicator.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if  ! simulate; then
	printf "Simulate shouldn't fail with \"in_init\" expression.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

comment
##
# Clear times counter
echo "0" > "${point_dir}/times"

if test $? -ne 0; then
	printf "Cannot clear times counter.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

echo "times % 2" > "${point_dir}/expression"

if test $? -ne 0; then
	printf "Cannot set expression for the indicator.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if  simulate; then
	printf "The first call to the function should fail with \"times %% 2\" expression.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if  ! simulate; then
	printf "The second call to the function shouldn't fail with \"times %% 2\" expression.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if  simulate; then
	printf "The third call to the function should fail with \"times %% 2\" expression.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi
# Now 'times' is 3, and next call of simulate shouldn't fail.
# But if we clear counter before simulate, it should.
echo 0 > ${point_dir}/times

times_current=`cat ${point_dir}/times`
if test $times_current != '0'; then
	printf "Expected that function call counter('times') should be cleared after writing to 'times' file, but it is '%s'.\n" "$times_current"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if  simulate; then
	printf "The fourth call to the function should fail with \"times %% 2\" expression because of clearing calls counter.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi


##
echo "$indicator_name" > "${point_dir}/current_indicator"
echo "1" > "${point_dir}/expression"
echo $$ > "${point_dir}/pid"

if test $? -ne 0; then
	printf "Cannot set 'pid' constraint on the indicator.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if  simulate; then
	printf "Simulate should fail within the shell that has set its pid for the indicator.\n"
	$do_commands_script "$commands_file" unload
	exit 1
fi

if ! $do_commands_script "$commands_file" unload; then
	printf "Errors occured while finalizing the test.\n"
	exit 1
fi
